from tortoise import fields, models


class RoleModel(models.Model):
    """角色模型"""
    
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=50, unique=True, description="角色名称")
    code = fields.CharField(max_length=50, unique=True, description="角色编码")
    description = fields.TextField(null=True, description="角色描述")
    permissions = fields.JSONField(default=list, description="权限列表")
    sort_order = fields.IntField(default=0, description="排序")
    is_active = fields.BooleanField(default=True, description="是否激活")
    is_system = fields.BooleanField(default=False, description="是否系统角色")
    remark = fields.TextField(null=True, description="备注")
    created_at = fields.DatetimeField(auto_now_add=True, description="创建时间")
    updated_at = fields.DatetimeField(auto_now=True, description="更新时间")

    class Meta:
        """模型元数据
        
        - table: 指定数据库表名
        - table_description: 表描述，用于数据库文档
        """
        table = "roles"
        table_description = "角色表"

    def __str__(self):
        """返回角色的字符串表示，用于调试和显示"""
        return self.name

    async def get_users(self):
        """获取拥有此角色的用户列表"""
        from app.modules.users.models import UserModel
        return await UserModel.filter(role_id=self.id)

    async def get_permission_objects(self):
        """获取角色的权限对象列表
        
        Returns:
            List[PermissionModel]: 权限对象列表
        """
        from app.modules.permissions.models import PermissionModel
        if not self.permissions:
            return []
        return await PermissionModel.filter(code__in=self.permissions, is_active=True)

    async def get_menu_permissions(self):
        """获取角色的菜单权限
        
        Returns:
            List[PermissionModel]: 菜单权限列表
        """
        from app.modules.permissions.models import PermissionModel
        if not self.permissions:
            return []
        return await PermissionModel.filter(
            code__in=self.permissions, 
            type="menu", 
            is_active=True, 
            is_visible=True
        )

    async def get_button_permissions(self):
        """获取角色的按钮权限
        
        Returns:
            List[PermissionModel]: 按钮权限列表
        """
        from app.modules.permissions.models import PermissionModel
        if not self.permissions:
            return []
        return await PermissionModel.filter(
            code__in=self.permissions, 
            type="button", 
            is_active=True
        )

    async def get_api_permissions(self):
        """获取角色的接口权限
        
        Returns:
            List[PermissionModel]: 接口权限列表
        """
        from app.modules.permissions.models import PermissionModel
        if not self.permissions:
            return []
        return await PermissionModel.filter(
            code__in=self.permissions, 
            type="api", 
            is_active=True
        )

    def has_permission(self, permission_code: str) -> bool:
        """检查角色是否拥有指定权限
        
        Args:
            permission_code: 权限编码
            
        Returns:
            bool: 是否拥有权限
        """
        if not self.permissions:
            return False
        return permission_code in self.permissions

    def has_any_permission(self, permission_codes: list) -> bool:
        """检查角色是否拥有任意一个指定权限
        
        Args:
            permission_codes: 权限编码列表
            
        Returns:
            bool: 是否拥有任意一个权限
        """
        if not self.permissions:
            return False
        return any(code in self.permissions for code in permission_codes)

    def has_all_permissions(self, permission_codes: list) -> bool:
        """检查角色是否拥有所有指定权限
        
        Args:
            permission_codes: 权限编码列表
            
        Returns:
            bool: 是否拥有所有权限
        """
        if not self.permissions:
            return False
        return all(code in self.permissions for code in permission_codes)

    def add_permission(self, permission_code: str):
        """添加权限到角色
        
        Args:
            permission_code: 权限编码
        """
        if not self.permissions:
            self.permissions = []
        if permission_code not in self.permissions:
            self.permissions.append(permission_code)

    def add_permissions(self, permission_codes: list):
        """批量添加权限到角色
        
        Args:
            permission_codes: 权限编码列表
        """
        if not self.permissions:
            self.permissions = []
        for code in permission_codes:
            if code not in self.permissions:
                self.permissions.append(code)

    def remove_permission(self, permission_code: str):
        """从角色中移除权限
        
        Args:
            permission_code: 权限编码
        """
        if self.permissions and permission_code in self.permissions:
            self.permissions.remove(permission_code)

    def remove_permissions(self, permission_codes: list):
        """批量从角色中移除权限
        
        Args:
            permission_codes: 权限编码列表
        """
        if self.permissions:
            for code in permission_codes:
                if code in self.permissions:
                    self.permissions.remove(code)

    def clear_permissions(self):
        """清空角色所有权限"""
        self.permissions = []

    async def sync_permissions(self, permission_codes: list):
        """同步角色权限（完全替换）
        
        Args:
            permission_codes: 新的权限编码列表
        """
        self.permissions = permission_codes.copy()
        await self.save()

    @classmethod
    async def get_by_code(cls, code: str):
        """根据角色编码获取角色
        
        Args:
            code: 角色编码
            
        Returns:
            RoleModel: 角色对象，如果不存在返回None
        """
        return await cls.filter(code=code).first()

    @classmethod
    async def get_active_roles(cls):
        """获取所有激活的角色
        
        Returns:
            QuerySet: 激活的角色查询集
        """
        return cls.filter(is_active=True).order_by('sort_order', 'id')

    @classmethod
    async def get_system_roles(cls):
        """获取系统角色
        
        Returns:
            QuerySet: 系统角色查询集
        """
        return cls.filter(is_system=True, is_active=True)

    @classmethod
    async def get_custom_roles(cls):
        """获取自定义角色
        
        Returns:
            QuerySet: 自定义角色查询集
        """
        return cls.filter(is_system=False, is_active=True)

    @classmethod
    async def get_roles_with_permissions(cls):
        """获取所有角色及其权限信息
        
        Returns:
            List[Dict]: 角色及其权限信息列表
        """
        roles = await cls.get_active_roles()
        result = []
        for role in roles:
            permission_objects = await role.get_permission_objects()
            role_data = {
                'id': role.id,
                'name': role.name,
                'code': role.code,
                'description': role.description,
                'permissions': role.permissions,
                'permission_objects': [
                    {
                        'id': p.id,
                        'name': p.name,
                        'code': p.code,
                        'type': p.type
                    } for p in permission_objects
                ]
            }
            result.append(role_data)
        return result
